#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/signal.h>
#include <linux/mutex.h>
#include <linux/mm.h>
#include <linux/timer.h>
#include <linux/wait.h>
#include <linux/skbuff.h>
#include <linux/proc_fs.h>
#include <linux/poll.h>
#include <linux/capi.h>
#include <linux/kernelcapi.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/moduleparam.h>

#include "My_Button_drv.h"

static struct button_operations *board_opt;
static int major = 0;
static struct class *button_class;

static int button_open(struct inode *inode, struct file *file)
{
	int minor = iminor(inode);
	board_opt->init(minor);
	return 0;
}

static ssize_t button_read(struct file *file, char __user *user, size_t size, loff_t *off)
{
	struct inode *inode = file_inode(file); // 从file结构体中提取出它所关联的inode结构体指针
	int minor = iminor(inode); // 获取次设备号
	char level;
	int err;

	level = board_opt->read(minor);
	err = copy_to_user(user, &level, 1);

	return 1;
}

static struct file_operations button_fops = {
	.owner = THIS_MODULE,
	.open = button_open,
	.read = button_read,
};


void button_create(struct button_operations *opt)
{
	int i = 0;
	
	board_opt = opt;
	
	for(i = 0; i < board_opt->count; i++)
	{
		device_create(button_class, NULL, MKDEV(major, i), NULL, "my_button@%d", i);
	}
}

void button_destroy(void)
{
	int i = 0;
	
	for(i = 0; i < board_opt->count; i++)
	{
		device_destroy(button_class, MKDEV(major, i));
	}
}

EXPORT_SYMBOL(button_create);
EXPORT_SYMBOL(button_destroy);

static int __init button_init(void)
{
	major = register_chrdev(0, "my_button", &button_fops);
	button_class = class_create(THIS_MODULE, "button_class");

	return 0;
}

static void __exit button_exit(void)
{
	class_destroy(button_class);
	unregister_chrdev(major, "button_class");
}

module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("GPL");



